﻿using System.Diagnostics.Contracts;
using System.Linq;

namespace Leek.Persistence
{
    public sealed class DomainObjectLink<T, TId>
        where T : DomainObject<T, TId>
    {
        private readonly DomainContext _context;
        private readonly DomainObjectId<T, TId> _id;
        private T _instance;


        public DomainObjectId<T, TId> Id
        {
            [Pure]
            get { return _id; }
        }


        internal DomainObjectLink(DomainObjectId<T, TId> id)
        {
            _context = id.Context;
            _id = id;
            _instance = null;
        }

        internal DomainObjectLink(T instance)
        {
            _context = instance.Context;
            _id = instance.Id;
            _instance = instance;
        }


        public T Get()
        {
            if (_instance == null && !_context.TryGet<T, TId>(_id, out _instance))
            {
                var repository = CompositionContainer.GetInstance<IDomainObjectRepository<T, TId>>();
                _instance = repository.Load(_context, null).Single(x => x.Id.Equals(_id)); //TODO: Optimize via FilterExpression!
            }

            return _instance;
        }
    }
}
